/**
 * Created by shengjian.lin on 17-1-10.
 */
var templateEngine = function () {

    var database = {};

    return {
        /**
         * 打印 将模板和数据进行组合成静态页面
         *
         * foreach 循环体 value 输出域
         *
         * data-variate 数据值，存放公式等
         * data-type 输出类型
         * data-value 最终值
         *
         * @param tp 模板 字符串
         * @param data 数据
         * @returns {string} 静态界面字符串
         */
        parsing:function (tp,data) {

            if(data==undefined||data==null)
                data={};

            var result = '';
            $(tp).each(function () {
                if(typeof($(this).attr("foreach"))!="undefined"){
                    //循环体
                    var array = data[$(this).attr('data-variate')];
                    var ctp = this.outerHTML;
                    for(var key in array){
                        var value = array[key];
                        //构建新的data
                        var newData = {};
                        for(var k in value){
                            newData[k] = value[k];
                        }
                        //判断值类型，数组或对象不进行组合
                        for(var k in data){
                            if(data[k].constructor != Array && data[k].constructor != Object){
                                newData[k] = data[k];
                            }
                        }
                        $(this).attr('data-index',key);
                        $(this).removeAttr('foreach');
                        result += templateEngine().parsing(this.outerHTML,newData);
                    }
                    result += ctp;
                }else if(this.nodeName.toUpperCase() == 'value'.toUpperCase()){

                    //数据值，直接计算数据
                    var variate = $(this).attr('data-variate');//参数名
                    var formula = $(this).attr('data-formula');//公式
                    var value;//最终值

                    if(formula == undefined){
                        //不存在公式，直接取值
                        value = data[variate];
                        if(value == undefined)
                            value = '';
                    }else{
                        //存在公式，进行计算
                        for(var key in data){
                            //通过正则表达式替换公式中的变量，换成变量对应的值
                            var reg = eval('/(\\b'+key+'\\b)/');
                            formula = formula.replace(reg,data[key]);
                        }

                        try {
                            //计算
                            value = eval(formula)
                        } catch (e){
                            value = '';
                        }
                    }

                    if($.isEmptyObject(value)){
                        var defaultValue = $(this).attr('data-value');
                        if(defaultValue != undefined)
                            value = defaultValue;
                    }

                    //界面显示
                    var inputType = $(this).attr('input-type');
                    if('select' == inputType){
                        //下拉选择类型
                        var option = eval($(this).attr('select-option'));//下拉的选项
                        var html = '<select class="form-control" disabled control>';
                        $(option).each(function () {
                            html += '<option value="'+this.value+'" '+(this.value==value?'selected':'')+'>'+this.name+'</option>';
                        });
                        html += '</select>';
                        $(this).html(html);
                    }else if('number' == inputType){
                        //数值型
                        $(this).html('<input class="form-control" type="number" value="'+value+'" disabled control>');
                    }else if('string' == inputType){
                        //字符型
                        $(this).html('<input class="form-control" type="text" value="'+value+'" disabled control>');
                    }else if('boolean' == inputType){
                        //布尔型
                        if(value.constructor != Boolean){
                            if(value == 0)
                                value = false;
                            else
                                value = true;
                        }
                        $(this).html('<input type="checkbox" '+(value?'checked':'')+' disabled control>');
                    }else{
                        $(this).text(value);
                    }


                    result += this.outerHTML == undefined ? '' : this.outerHTML;
                }else{
                    //html标签
                    var ctp = '';
                    $(this).children().each(function () {
                        if(this.outerHTML != undefined){
                            ctp += templateEngine().parsing(this.outerHTML,data);
                        }
                    });

                    if(!$.isEmptyObject(ctp))
                        $(this).html(ctp);

                    result += this.outerHTML == undefined ? '' : this.outerHTML;
                }
            });

            return result;
        },
        formula:function (el,data) {
            $(el).find('value[data-formula]').each(function () {

                var formula = $(this).attr('data-formula')
                var variate = formula.match(/\b[A-Za-z0-9]\w+\b/g);
                $(variate).each(function () {
                    var _el = $(el).find('value[data-variate='+this+']');
                    var value;
                    if(_el.length == 0){
                        value = data[variate];
                    }else{
                        value = $(_el).find('[control]').val();

                        if($.isEmptyObject(value)){
                            value = $(_el).attr('data-value');
                        }
                        //如果从界面中没取得值，就试试传递的变量中是否有
                        if($.isEmptyObject(value))
                            value = data[variate];
                    }
                    if(!$.isEmptyObject(value) || typeof value == "number"){
                        var reg = eval('/(\\b'+this+'\\b)/');
                        formula = formula.replace(reg,value);
                    }
                });
                var value;
                try {
                    value = eval(formula);
                } catch (e){
                    value = '';
                }

                $(this).text(value);
            });
        },
        input:function (el,data) {
            $(el).find('value [disabled]').removeAttr('disabled');
            $(el).find('value [control]').change(function () {

                var el = $(this).parent('value');

                if(el.length > 0){

                    var value = $(this).val();

                    var index = $(el).attr('data-index');
                    var key = $(el).attr('data-variate');
                    if($.isEmptyObject(index)){
                        database[key]=value;
                    }else{
                        var arry_key = $(el).parents('tr').attr('data-variate');
                        if(database[arry_key]==undefined)
                            database[arry_key] = [];

                        database[arry_key][index] = {};
                        database[arry_key][index][key] = value;
                    }
                }

            });
            $(el).find('value').each(function () {
                var el = this;
                var formula = $(this).attr('data-formula');
                var foreach = $(this).parents('[data-index]').attr('data-index');
                var _data = data;
                if(foreach != undefined){
                    var array = data[$(this).parents('[data-index]').attr('data-variate')][foreach];
                    _data = {};
                    for(var key in array){
                        _data[key] = array[key];
                    }
                    //判断值类型，数组或对象不进行组合
                    for(var key in data){
                        if(data[key].constructor != Array && data[key].constructor != Object){
                            _data[key] = data[key];
                        }
                    }
                }
                if(formula != undefined){
                    var variate = formula.match(/\b[A-Za-z0-9]\w+\b/g);
                    var controls = [];
                    $(variate).each(function () {
                        var control = $('value[data-variate='+this+'] [control]');
                        if(control.length == 0){
                            var value;
                            var _control = $('value[data-variate='+this+']');
                            if(_control.length == 0)
                                value = _data[this];
                            else
                                value = _control.text();
                            if(value != undefined && value.constructor != Array && value.constructor != Object){

                                if(value.constructor == Boolean){
                                    if(value)
                                        value = 1;
                                    else
                                        value = 0;
                                }

                                var reg = eval('/(\\b'+this+'\\b)/');
                                formula = formula.replace(reg,value);
                            }
                            return;
                        }else if(control.length > 1){
                            control = $('[data-index='+foreach+'] value[data-variate='+this+'] [control]');
                        }
                        control.change(function () {
                            var _formula = formula;
                            $(controls).each(function () {
                                var key = this.parent().attr('data-variate');
                                var reg = eval('/(\\b'+key+'\\b)/');
                                _formula = _formula.replace(reg,this.val());
                            });
                            var value;
                            try {
                                value = eval(_formula);
                            } catch (e){
                                value = '';
                            }

                            var inputType = $(el).attr('input-type');
                            if('select' == inputType){
                                //下拉选择类型
                                $(el).children('select>option:selected').removeAttrs(selected);
                                $(el).children('select>option[value='+value+']').attr(selected,true);

                            }else if('number' == inputType){
                                //数值型
                                $(el).children('input').val(value);
                            }else if('string' == inputType){
                                //字符型
                                $(el).children('input').val(value);
                            }else if('boolean' == inputType){
                                //布尔型
                                if(value.constructor != Boolean){
                                    if(value == 0)
                                        value = false;
                                    else
                                        value = true;
                                }
                                $(el).children('input').attr('checked',value);
                            }else{
                                $(el).text(value);
                            }
                            var index = $(el).attr('data-index');
                            var key = $(el).attr('data-variate');
                            if($.isEmptyObject(index)){
                                database[key]=value;
                            }else{
                                var arry_key = $(el).parents('tr').attr('data-variate');
                                if(database[arry_key]==undefined)
                                    database[arry_key] = [];

                                database[arry_key][index] = {};
                                database[arry_key][index][key] = value;
                            }

                        });

                        controls.push(control);
                    });
                }
            });
        },
        data:database,
    };
};